Updated upstream ======= >>>>>>> Stashed changes
TODO :
- Vérifier qu’il n’y a plus de TODO dans le fichier.
- Ajouter des images, diagrammes et extraits de code.
- Ajouter des échantillons de données pour expliciter chaque étape.
Prédire les résultats d’éléctions présidentielles française d’un bureau de vote.
Les préférences politiques des individus peuvent être façonnées par des variables socio-démographiques telles que l’âge, le niveau d’éducation, la situation économique ou encore le lieu de résidence. Plusieurs cadres théoriques permettent de formuler des hypothèses sur ces influences potentielles.
La théorie de la socialisation politique suppose que des facteurs comme l’âge, le genre et la composition familiale jouent un rôle dans la formation des opinions politiques. Par exemple, on pourrait s’attendre à ce que les jeunes adultes soient plus attirés par des idées progressistes, tandis que les générations plus âgées privilégient des positions conservatrices, influencées par leurs expériences passées.
Les théories liées au clivage de classe sociale, inspirées par les travaux de Karl Marx et Pierre Bourdieu, postulent que la position des individus dans la hiérarchie socio-professionnelle peut orienter leurs préférences politiques. Les individus occupant des emplois manuels ou précaires pourraient être davantage sensibles aux discours en faveur de la justice sociale, tandis que les catégories socio-professionnelles supérieures seraient plus réceptives aux politiques favorisant l’investissement et la stabilité économique.
Le capital culturel, tel que défini par Pierre Bourdieu, pourrait également jouer un rôle dans le comportement électoral. Les niveaux de qualification peuvent influencer la perception des enjeux politiques : les personnes disposant d’un diplôme supérieur pourraient privilégier des valeurs universalistes et libérales, alors que les moins diplômés pourraient être plus sensibles aux discours protectionnistes ou nationalistes.
La théorie du contexte géographique met en avant l’importance du lieu de vie et des interactions sociales locales sur les comportements politiques. Les caractéristiques urbaines et rurales, la proportion de logements sociaux ou encore l’ancienneté des constructions peuvent être des indicateurs pertinents pour comprendre les dynamiques électorales locales.
La théorie de la privation relative suggère que les inégalités perçues entre les attentes des individus et leur situation réelle peuvent les amener à soutenir des mouvements politiques contestataires. Des indicateurs comme le taux de pauvreté, le niveau de vie ou la précarité de l’emploi pourraient refléter ce sentiment de frustration.
Enfin, la théorie du choix rationnel propose que les électeurs adoptent des comportements stratégiques, en cherchant à maximiser leurs bénéfices individuels à travers leurs choix politiques. Par exemple, les propriétaires immobiliers ou les ménages vivant seuls pourraient orienter leurs votes en fonction des politiques perçues comme avantageuses ou défavorables à leurs intérêts.
Quel lien existe entre les différents facteurs socio-démographiques et influencent-ils les choix politiques des citoyens ?
L’objectif est d’explorer ces hypothèses théoriques en s’appuyant sur des données socio-démographiques et électorales de plusieurs années. Cette étape théorique permet de poser les bases d’une analyse empirique qui pourra confirmer ou infirmer ces hypothèses en fonction des observations. Nous étudierons les liens au travers de différentes techniques d’analyse statistiques.
D’après le cadre théorique, la première étape consiste à collecter les résultats des élections présidentielles. Pour enrichir notre jeu de données, nous avons choisi de les détailler au niveau des bureaux de vote. La plateforme data.gouv.fr nous donne accès à ce type de données. Lors de chaque élection, environ 70 000 bureaux de vote partagent leurs résultats. Nous limiterons toutefois notre étude aux trois dernières élections présidentielles (2012, 2017 et 2022), ce qui sera largement suffisant pour répondre à notre problématique.
De plus, nous nous concentrerons uniquement sur les bureaux de vote situés en France métropolitaine afin de simplifier la visualisation des données sur une carte. Cette restriction n’a qu’un faible impact sur la représentativité globale du jeu de données.
À partir du cadre théorique, nous avons identifié plusieurs groupes de facteurs socio-démographiques susceptibles d’influencer les orientations politiques des individus :
Facteurs démographique : ce groupe comprend des variables telles que l’âge, le genre et la composition familiale. Ces éléments permettent d’évaluer l’impact de la socialisation politique, notamment l’influence des générations et des expériences de vie sur le comportement électoral.
Facteurs travail et revenus : ces variables incluent la catégorie socio-professionnelle, le type d’emploi (salarié ou indépendant), le taux d’activité et le niveau de vie. Elles permettent d’explorer le rôle des disparités économiques et de la hiérarchie sociale sur les préférences politiques, en lien avec la théorie du clivage de classe.
Facteurs éducation : le niveau de diplôme et les qualifications constituent des indicateurs clés du capital culturel. Ces données sont utiles pour comprendre la manière dont l’accès au savoir et la formation influencent la perception des enjeux politiques.
Facteurs lieu de vie : ce groupe comprend des variables liées au lieu de résidence, telles que la répartition urbaine ou rurale, la proportion de logements sociaux, et l’ancienneté des constructions. Ces éléments permettent d’examiner l’impact du contexte spatial et des interactions sociales locales sur le vote.
Facteurs conditions de vie : le taux de pauvreté, la précarité de l’emploi et la composition des ménages permettent de mesurer le sentiment de privation relative et son effet potentiel sur l’adhésion à des mouvements politiques contestataires.
Facteurs mode de vie : certaines variables, comme la propriété immobilière ou la structure des ménages (par exemple, vivre seul ou en famille), peuvent refléter des comportements électoraux stratégiques, en lien avec des choix rationnels visant à préserver ou à optimiser une situation personnelle.
Certaines de ces données ont été directement récupérées sur le site de l’INSEE, via des études ou des cartes interactives avec export de données (par exemple, statistiques-locales.insee.fr). Ces données étant regroupées par commune, nous avons pu les répartir proportionnellement entre les bureaux de vote en fonction du nombre de votants.
En revanche, la collecte des données concernant les revenus, le lieu de vie et les conditions de vie a été plus complexe. Ces données sont fournies sous forme de « carreaux » géographiques de 200 mètres de côté. Il a donc été nécessaire de récupérer les contours géographiques des bureaux de vote, de convertir et harmoniser les formats de coordonnées (CRS), puis de fusionner ces ensembles de données. La librairie R sf a été utilisée pour effectuer ces opérations, notamment en croisant les carreaux de 200 mètres avec les contours des bureaux de vote. Cette tâche s’est avérée chronophage en raison du coût computationnel élevé des calculs nécessaires pour chaque opération. Certaines données ont dû être additionnées, d’autres moyennées. Une vérification finale a montré une perte de seulement 0,01 % des données, ce qui constitue un excellent résultat pour ce type de fusion géographique.
Les données ont été vérifiées afin d’éviter les valeurs aberrantes et garantir leur cohérence. Certaines transformations ont également été effectuées pour faciliter la visualisation et les rendre compatibles avec notre modèle d’analyse.
Le point de centralisation des données est le “code bureau de vote”, un identifiant unique attribué à chaque bureau de vote.
Pour les résultats des élections, il a d’abord été nécessaire de transformer la liste des votes par candidat dans chaque bureau de vote en catégories agrégées correspondant aux principaux courants politiques : Extrême Gauche, Gauche, Centre, Droite et Extrême Droite. Cette étape permet de simplifier l’analyse des tendances politiques tout en conservant une granularité suffisante.
Une colonne “Code” a été ajoutée en combinant les codes du département, de la commune et du bureau de vote, ce qui facilite la fusion avec d’autres jeux de données. Certaines colonnes, telles que les noms des départements ou les pourcentages inutiles (ex. : % Abstentions/Inscrits), ont été supprimées pour alléger le jeu de données. Une colonne “nonExp” a été créée pour regrouper les bulletins blancs et nuls. Cette information nous aide à mieux comprendre les niveaux de participation et de contestation.
Les données finales ont été organisées de manière à regrouper les colonnes liées à chaque courant politique, en mettant en avant les variables principales (comme les pourcentages par votant, inscrits et suffrages exprimés).
Un extrait des données nettoyées et organisées est présenté ci-dessous :
<<<<<<< Updated upstream| Annee | Code | Libellé de la commune | Votants | nonExp | VoixEG | % Voix/VotantEG | VoixG | % Voix/VotantG | VoixC | % Voix/VotantC | VoixD | % Voix/VotantD | VoixED | % Voix/VotantED |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2022 | 010010001 | L'Abergement-Clémenciat | 537 | 17 | 6 | 1.117318 | 107 | 19.92551 | 168 | 31.28492 | 47 | 8.752328 | 192 | 35.75419 |
| 2022 | 010020001 | L'Abergement-de-Varey | 175 | 4 | 5 | 2.857143 | 61 | 34.85714 | 60 | 34.28571 | 8 | 4.571429 | 37 | 21.14286 |
| 2022 | 010040001 | Ambérieu-en-Bugey | 863 | 23 | 12 | 1.390498 | 286 | 33.14021 | 183 | 21.20510 | 53 | 6.141367 | 306 | 35.45771 |
Concernant les facteurs socio-démographiques, certaines données étaient déjà disponibles au niveau des bureaux de vote, tandis que d’autres étaient regroupées au niveau communal. Ces dernières ont été réparties entre les bureaux de vote en suivant une répartition proportionnelle basée sur le nombre de votants, comme décrit précédemment.
Afin de préparer la visualisation de nos données sur des cartes, nous avons conservé un fichier spatial au format GeoJSON contenant les contours des bureaux de vote, identifiés par l’ID code_bureau_vote. Ce fichier, d’une taille de 600 Mo, a été isolé pour éviter de ralentir le traitement des données lors des analyses statistiques. En cas de besoin, il peut être facilement fusionné avec notre jeu de données pour générer des visualisations cartographiques.
Ces étapes ont permis de disposer d’un jeu de données homogène et prêt pour l’analyse statistique des corrélations entre les variables socio-démographiques et les résultats électoraux. Voici un échantillon des 72 colonnes finales :
<<<<<<< Updated upstream| code_bureau_vote | votants | non_exp | voix_eg | pourcentage_voix_votant_eg | voix_g | pourcentage_voix_votant_g | voix_c | pourcentage_voix_votant_c | voix_d | pourcentage_voix_votant_d | voix_ed | pourcentage_voix_votant_ed | code_insee | population_ratio | libelle | nb_25 | nb_25_64 | nb_65 | prop_25 | prop_25_64 | prop_65 | taux_nat | taux_mort | nb_non_scolarises | part_non_peu_diplomes | part_bepc_brevet | part_cap_bep | part_bac | nb_h_total | nb_f_total | nb_h_15_24 | nb_h_25_64 | nb_h_65 | nb_f_15_24 | nb_f_25_64 | nb_f_65 | population_totale | proportion_h | proportion_f | nb_emplois_lt | taux_activite | part_emplois_salaries | part_agriculteurs | part_emplois_non_salaries | part_artisans | part_commercants | part_chefs_entreprise | part_cadres | part_prof_intermediaires | part_employes | part_ouvriers | annees | nb_menages | nb_menages_pauvres | nb_menages_seul | nb_menages_5plus | nb_menages_proprietaires | nb_menages_monoparentaux | niveau_vie_total | surface_totale_logements | nb_logements_collectifs | nb_logements_maisons | nb_log_avant_1945 | nb_log_1945_1969 | nb_log_1970_1989 | nb_log_apres_1990 | nb_log_date_inconnue | nb_logements_sociaux | part_bac2 | part_bac3_4 | part_bac5_plus |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 010010001 | 508 | 9 | 29 | 5.708661 | 125 | 24.6063 | 54 | 10.62992 | 165 | 32.48031 | 126 | 24.80315 | 01001 | 1.0000000 | L'Abergement-Clémenciat | 247.0000 | 409.000 | 128.0000 | 31.5 | 52.2 | 16.3 | 13.0 | 7.1 | 555.000 | 27.4 | 5.8 | 25.4 | 16.8 | 245.0000 | 231.0000 | 35.0000 | 163.0000 | 47.00000 | 32.000 | 148.0000 | 51.00000 | 476.000 | 0.515 | 0.485 | 73.0000 | 74.9 | 64.4 | 18.8 | 35.6 | 0.0 | 9.4 | 15.4 | 37.7 | 18.7 | 37.3 | 95.1 | 2008-2012 | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA |
| 010020001 | 179 | 5 | 17 | 9.497207 | 49 | 27.3743 | 22 | 12.29050 | 48 | 26.81564 | 38 | 21.22905 | 01002 | 1.0000000 | L'Abergement-de-Varey | 59.0000 | 124.000 | 39.0000 | 26.5 | 56.0 | 17.5 | 18.6 | 11.4 | 169.000 | 15.6 | 3.4 | 22.3 | 18.4 | 72.0000 | 69.0000 | 7.0000 | 51.0000 | 14.00000 | 10.000 | 45.0000 | 13.00000 | 141.000 | 0.511 | 0.489 | 17.0000 | 78.5 | 44.4 | 51.5 | 55.6 | 0.0 | 0.0 | 48.5 | 0.0 | 0.0 | 61.1 | 92.2 | 2008-2012 | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA |
| 010040001 | 800 | 19 | 118 | 14.750000 | 227 | 28.3750 | 74 | 9.25000 | 173 | 21.62500 | 189 | 23.62500 | 01004 | 0.1229445 | Ambérieu-en-Bugey | 589.2731 | 855.325 | 256.3393 | 34.6 | 50.3 | 15.1 | 14.2 | 7.6 | 1205.963 | 28.1 | 6.7 | 24.5 | 18.6 | 556.0781 | 532.1039 | 122.0839 | 350.6378 | 83.47933 | 110.773 | 333.9173 | 87.29061 | 1088.182 | 0.511 | 0.489 | 949.0088 | 74.4 | 90.6 | 0.1 | 9.4 | 5.5 | 11.2 | 26.9 | 33.0 | 23.4 | 55.2 | 90.3 | 2008-2012 | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA |
L’analyse des données doit être la plus précise possible. Pour cela, nous avons choisi de créer un jeu de données intermédiaire qui élimine la duplication des bureaux de vote sur plusieurs années. Nous sélectionnerons aléatoirement une seule observation par bureau de vote parmi différentes années afin d’éviter un biais de similitude. En effet, un bureau ayant historiquement voté à droite a de fortes chances de continuer à voter de la même manière, ce qui pourrait fausser l’analyse si nous incluons plusieurs observations temporelles sans ajustement.
Nous ajoutons également une variable score comprise entre 0 et 1, qui
indique l’orientation politique moyenne :
- 0 correspond à l’extrême gauche,
- 0.5 représente le centre,
- 1 correspond à l’extrême droite.
data <- data %>%
mutate(
score_orientation = round(
(voix_ed * 1 + voix_d * 0.75 + voix_c * 0.5 + voix_g * 0.25 + voix_eg * 0) /
(voix_eg + voix_g + voix_c + voix_d + voix_ed),
2
)
) %>%
filter(!is.na(score_orientation))
score_moyen <- mean(data$score_orientation)
# Intervalle de confiance
n <- length(data$score_orientation)
score_var <- var(data$score_orientation)
alpha <- 0.05
quant_stud <- qt(1-alpha/2, df=n-1)
borne_inf <- score_moyen - quant_stud * sqrt(score_var/n)
borne_sup <- score_moyen + quant_stud * sqrt(score_var/n)
paste(borne_inf, "<", score_moyen, "<", borne_sup)
## [1] "0.582033290776292 < 0.582397657293833 < 0.582762023811374"
Cela indique que l’orientation politique française actuelle se situe plutôt au centre-droit.
Notre objectif initial est d’explorer la corrélation entre le niveau de richesse et l’orientation politique. Les politiques de droite étant souvent perçues comme plus favorables aux personnes disposant de revenus élevés, il est raisonnable d’anticiper une corrélation positive entre un haut niveau de richesse et un soutien aux partis de droite.
N’ayant pas de données sur le niveau de vie en 2012, nous ne séléctionnerons pas de datas sur cette année. Voici le dataset que nous utiliserons:
<<<<<<< Updated upstream| code_bureau_vote | votants | non_exp | voix_eg | pourcentage_voix_votant_eg | voix_g | pourcentage_voix_votant_g | voix_c | pourcentage_voix_votant_c | voix_d | pourcentage_voix_votant_d | voix_ed | pourcentage_voix_votant_ed | code_insee | population_ratio | libelle | nb_25 | nb_25_64 | nb_65 | prop_25 | prop_25_64 | prop_65 | taux_nat | taux_mort | nb_non_scolarises | part_non_peu_diplomes | part_bepc_brevet | part_cap_bep | part_bac | nb_h_total | nb_f_total | nb_h_15_24 | nb_h_25_64 | nb_h_65 | nb_f_15_24 | nb_f_25_64 | nb_f_65 | population_totale | proportion_h | proportion_f | nb_emplois_lt | taux_activite | part_emplois_salaries | part_agriculteurs | part_emplois_non_salaries | part_artisans | part_commercants | part_chefs_entreprise | part_cadres | part_prof_intermediaires | part_employes | part_ouvriers | annees | nb_menages | nb_menages_pauvres | nb_menages_seul | nb_menages_5plus | nb_menages_proprietaires | nb_menages_monoparentaux | niveau_vie_total | surface_totale_logements | nb_logements_collectifs | nb_logements_maisons | nb_log_avant_1945 | nb_log_1945_1969 | nb_log_1970_1989 | nb_log_apres_1990 | nb_log_date_inconnue | nb_logements_sociaux | part_bac2 | part_bac3_4 | part_bac5_plus | score_orientation |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 782900001 | 611 | 18 | 10 | 1.636661 | 144 | 23.56792 | 149 | 24.38625 | 50 | 8.183306 | 240 | 39.27987 | 78290 | 1.00000000 | Guernes | 330.0000 | 585.0000 | 160.0000 | 30.7 | 54.4 | 14.9 | 9.7 | 5.9 | 714 | 16.2 | 3.7 | 30.0 | 22.2 | 352.000 | 343.0000 | 54.00000 | 226.0000 | 72.0000 | 57.00000 | 223.0000 | 63.00000 | 695.0000 | 0.506 | 0.494 | 66.000 | 80.4 | 66.3 | 0.0 | 33.7 | 22.7 | 21.9 | 22.1 | 31.0 | 2.3 | 94.9 | 60.0 | 2018-2022 | 415.866 | 24.200 | 102.979 | 37.388 | 344.313 | 32.646 | 28540226 | 40504.55 | 25.192 | 390.674 | 163.916 | 55.237 | 75.811 | 120.902 | 0 | 1.200 | 13.9 | 8.2 | 5.7 | 0.65 |
| 621190008 | 710 | 22 | 14 | 1.971831 | 182 | 25.63380 | 145 | 20.42254 | 132 | 18.591549 | 215 | 30.28169 | 62119 | 0.05720732 | Béthune | 457.9446 | 721.0982 | 250.7969 | 32.0 | 50.4 | 17.5 | 14.2 | 10.2 | =======|||||||||||||||||||||||||||||||||||||||||||||||||
| 613320001 | 219 | 3 | 4 | 1.8264840 | 22 | 10.04566 | 72 | 32.87671 | 76 | 34.703196 | 42 | 19.17808 | 61332 | 1 | Pointel | 96 | 169 | 59 | 29.6 | 52.2 | 18.2 | 9.6 | 7.0 | >>>>>>> Stashed changesNA | NA | NA | NA | NA | <<<<<<< Updated upstream469.386 | 461.7775 | 77.91636 | 277.9131 | 113.4993 | 92.04657 | 273.2221 | 96.50874 | 931.1635 | 0.504 | 0.496 | 1002.787 | 65.5 | 92.5 | 0.2 | 7.5 | 4.0 | 14.4 | 25.4 | 33.4 | 22.7 | 81.5 | 43.2 | 2013-2017 | 618.729 | 126.135 | 256.862 | 41.602 | 222.080 | 86.473 | 24562199 | 50055.73 | 256.433 | 362.296 | 148.088 | 62.160 | 76.085 | 332.395 | 0 | 215.635 | NA | NA | NA | 0.63 |
| 030460001 | 586 | 21 | 9 | 1.535836 | 189 | 32.25256 | 124 | 21.16041 | 32 | 5.460751 | 211 | 36.00683 | 03046 | 1.00000000 | Buxières-les-Mines | 199.0000 | 472.0000 | 332.0000 | 19.9 | 47.1 | 33.1 | 6.7 | 16.2 | 879 | 31.3 | 6.0 | 31.3 | 15.4 | 274.000 | 271.0000 | 29.00000 | 150.0000 | 95.0000 | 43.00000 | 137.0000 | 90.00000 | 545.0000 | 0.503 | 0.497 | 216.000 | 66.8 | 67.2 | 24.9 | 32.8 | 7.7 | 11.6 | 5.8 | 19.4 | 30.7 | 87.2 | 44.9 | 2018-2022 | 507.224 | 113.159 | 203.251 | 20.086 | 374.403 | 51.689 | 19421350 | 43788.98 | 55.510 | 451.714 | 374.843 | 13.737 | 91.797 | 26.847 | 0 | 52.100 | 7.2 | 5.8 | 3.0 | 0.61 | 115 | 92 | 23 | 63 | 29 | 25 | 58 | 9 | 207 | 0.556 | 0.444 | 120 | 80.7 | 75.0 | 9.2 | 25.0 | 27 | 0 | 43.1 | 4.6 | 16.0 | 100.0 | 56.2 | 2013-2017 | 124.766 | 14.694 | 25.656 | 8.555 | 99.376 | 8.477 | 6686921 | 13143.678 | 0.000 | 124.766 | 48.300 | 10.383 | 26.567 | 39.516 | 0 | 0 | NA | NA | NA | 0.65 |
| 120180001 | 150 | 3 | 2 | 1.3333333 | 44 | 29.33333 | 40 | 26.66667 | 32 | 21.333333 | 29 | 19.33333 | 12018 | 1 | Balaguier-d'Olt | 33 | 93 | 32 | 20.8 | 59.1 | 20.1 | 18.8 | 10.1 | NA | NA | NA | NA | NA | 47 | 57 | 12 | 30 | 5 | 19 | 32 | 6 | 104 | 0.452 | 0.548 | 22 | 74.5 | 63.7 | 0.0 | 36.3 | 20 | 0 | 0.0 | 40.1 | 39.9 | 90.0 | 51.6 | 2013-2017 | 70.700 | 10.200 | 17.900 | 3.300 | 55.800 | 7.300 | 3307431 | 7689.081 | 0.100 | 70.600 | 44.300 | 2.800 | 9.700 | 11.900 | 2 | 0 | NA | NA | NA | 0.57 |
| 653730001 | 115 | 0 | 1 | 0.8695652 | 30 | 26.08696 | 44 | 38.26087 | 6 | 5.217391 | 34 | 29.56522 | 65373 | 1 | Puntous | 24 | 82 | 53 | 15.2 | 51.5 | 33.3 | 2.8 | 16.0 | 172 | 20.5 | 9.6 | 25.3 | 22.6 | 48 | 48 | 9 | 26 | 13 | 5 | 25 | 18 | 96 | 0.500 | 0.500 | 5 | 79.8 | 0.0 | 100.0 | 100.0 | 0 | 0 | 0.0 | 0.0 | 0.0 | 96.2 | 62.5 | 2018-2022 | 85.896 | 16.758 | 30.288 | 0.900 | 65.747 | 8.300 | 3668317 | 10556.370 | 5.968 | 79.927 | 61.478 | 1.500 | 6.518 | 16.400 | 0 | 0 | 11 | 5.5 | 5.5 | 0.59 |
Observons rapidement la répartition des richesses en fonction des votes:
<<<<<<< Updated upstreamOn constate qu’effectivement le niveau de vie semble impacter le pourcentage de voix d’extrême gauche mais n’explique pas tout. Pour ce qui est de l’extrème droite, on observe une grande répartition donc le niveau de vie ne semble pas un facteur premier. Mais il y a tout de même cette tendance, ce qui laisse penser que la pauvreté pousse à voté dans les extrêmes.
Comparons maintenant avec notre score :
<<<<<<< Updated upstream
=======
>>>>>>> Stashed changes
Nous cherchons une diagonale allant de l’angle inférieur gauche vers
l’angle supérieur droit. Ce n’est pas le cas ici, ce qui indique que
l’influence de la richesse sur les votes n’est pas significative
lorsqu’elle est observée isolément. En revanche, notre théorie est
confirmée : plus le niveau de richesse est faible, plus les votes pour
les extrêmes augmentent.
En conclusion, la richesse permet simplement d’expliquer qu’un niveau de vie bas est associé à une probabilité plus élevée de vote pour les extrêmes.
Beaucoup de variable étant des quantités, il est intéressant de plutôt utiliser des proportions. Il faut également supprimer les colonnes inutiles car déjà représenté par d’autres (ex: Taux homme et Nb d’homme).
## code_bureau_vote votants pourcentage_voix_votant_eg pourcentage_voix_votant_g
## 1 010010001 508 5.708661 24.60630
## 2 010020001 179 9.497207 27.37430
## 3 010040001 800 14.750000 28.37500
## 4 010040002 869 12.773303 27.61795
## 5 010040003 846 13.120567 29.66903
## 6 010040004 828 13.043478 27.53623
## pourcentage_voix_votant_c pourcentage_voix_votant_d
## 1 10.629921 32.48031
## 2 12.290503 26.81564
## 3 9.250000 21.62500
## 4 7.479862 27.27273
## 5 8.865248 25.88652
## 6 7.971014 28.74396
## pourcentage_voix_votant_ed prop_25 prop_25_64 prop_65 taux_nat taux_mort
## 1 24.80315 31.5 52.2 16.3 13.0 7.1
## 2 21.22905 26.5 56.0 17.5 18.6 11.4
## 3 23.62500 34.6 50.3 15.1 14.2 7.6
## 4 22.78481 34.6 50.3 15.1 14.2 7.6
## 5 21.04019 34.6 50.3 15.1 14.2 7.6
## 6 21.01449 34.6 50.3 15.1 14.2 7.6
## part_non_peu_diplomes part_bepc_brevet part_cap_bep part_bac proportion_h
## 1 27.4 5.8 25.4 16.8 0.515
## 2 15.6 3.4 22.3 18.4 0.511
## 3 28.1 6.7 24.5 18.6 0.511
## 4 28.1 6.7 24.5 18.6 0.511
## 5 28.1 6.7 24.5 18.6 0.511
## 6 28.1 6.7 24.5 18.6 0.511
## proportion_f taux_activite part_emplois_salaries part_agriculteurs
## 1 0.485 74.9 64.4 18.8
## 2 0.489 78.5 44.4 51.5
## 3 0.489 74.4 90.6 0.1
## 4 0.489 74.4 90.6 0.1
## 5 0.489 74.4 90.6 0.1
## 6 0.489 74.4 90.6 0.1
## part_emplois_non_salaries part_artisans part_commercants
## 1 35.6 0.0 9.4
## 2 55.6 0.0 0.0
## 3 9.4 5.5 11.2
## 4 9.4 5.5 11.2
## 5 9.4 5.5 11.2
## 6 9.4 5.5 11.2
## part_chefs_entreprise part_cadres part_prof_intermediaires part_employes
## 1 15.4 37.7 18.7 37.3
## 2 48.5 0.0 0.0 61.1
## 3 26.9 33.0 23.4 55.2
## 4 26.9 33.0 23.4 55.2
## 5 26.9 33.0 23.4 55.2
## 6 26.9 33.0 23.4 55.2
## part_ouvriers annees part_bac2 part_bac3_4 part_bac5_plus
## 1 95.1 2008-2012 NA NA NA
## 2 92.2 2008-2012 NA NA NA
## 3 90.3 2008-2012 NA NA NA
## 4 90.3 2008-2012 NA NA NA
## 5 90.3 2008-2012 NA NA NA
## 6 90.3 2008-2012 NA NA NA
## score_orientation non_exp_prop_votants nb_non_scolarises_prop_votants
## 1 0.62 0.01771654 1.0925197
## 2 0.56 0.02793296 0.9441341
## 3 0.53 0.02375000 1.5074535
## 4 0.55 0.02071346 1.5074535
## 5 0.53 0.01418440 1.5074535
## 6 0.54 0.01690821 1.5074535
## niveau_vie_total_prop_votants nb_menages_prop_votants
## 1 NA NA
## 2 NA NA
## 3 NA NA
## 4 NA NA
## 5 NA NA
## 6 NA NA
## nb_emplois_lt_prop_votants nb_menages_pauvres_prop_nb_menages
## 1 0.14370079 NA
## 2 0.09497207 NA
## 3 1.18626095 NA
## 4 1.18626095 NA
## 5 1.18626095 NA
## 6 1.18626095 NA
## nb_menages_seul_prop_nb_menages nb_menages_5plus_prop_nb_menages
## 1 NA NA
## 2 NA NA
## 3 NA NA
## 4 NA NA
## 5 NA NA
## 6 NA NA
## nb_menages_proprietaires_prop_nb_menages
## 1 NA
## 2 NA
## 3 NA
## 4 NA
## 5 NA
## 6 NA
## nb_menages_monoparentaux_prop_nb_menages
## 1 NA
## 2 NA
## 3 NA
## 4 NA
## 5 NA
## 6 NA
## surface_totale_logements_prop_nb_menages
## 1 NA
## 2 NA
## 3 NA
## 4 NA
## 5 NA
## 6 NA
## nb_logements_collectifs_prop_nb_menages nb_logements_maisons_prop_nb_menages
## 1 NA NA
## 2 NA NA
## 3 NA NA
## 4 NA NA
## 5 NA NA
## 6 NA NA
## nb_log_avant_1945_prop_nb_menages nb_log_1945_1969_prop_nb_menages
## 1 NA NA
## 2 NA NA
## 3 NA NA
## 4 NA NA
## 5 NA NA
## 6 NA NA
## nb_log_1970_1989_prop_nb_menages nb_log_apres_1990_prop_nb_menages
## 1 NA NA
## 2 NA NA
## 3 NA NA
## 4 NA NA
## 5 NA NA
## 6 NA NA
## nb_log_date_inconnue_prop_nb_menages nb_logements_sociaux_prop_nb_menages
## 1 NA NA
## 2 NA NA
## 3 NA NA
## 4 NA NA
## 5 NA NA
## 6 NA NA
Comme nous venons de le voir, il est intéressant de ploter notre score face à nos différentes données, nous allons donc tous les tester rapidement et essayer d’observer.
analys_data_long <- analys_data_clean %>%
select(score_orientation, where(is.numeric)) %>%
select(-contains("voix")) %>%
pivot_longer(
cols = -score_orientation,
names_to = "variable",
values_to = "value"
)
p <- ggplot(analys_data_long, aes(x = score_orientation, y = value)) +
geom_point(alpha = 0.7, color = "blue") +
facet_wrap(~ variable, scales = "free_y") +
labs(
title = "Score d'orientation vs. autres variables",
x = "Score (0 = Extrême gauche, 1 = Extrême droite)",
y = "Variables"
) +
theme_minimal()
# Export en image pour une meilleur lecture
ggsave("scatterplot_matrix.png", plot = p, width = 12, height = 8, dpi = 300)
## Warning: Removed 36180 rows containing missing values or values outside the scale range
## (`geom_point()`).
p
## Warning: Removed 36180 rows containing missing values or values outside the scale range
## (`geom_point()`).
Comme nous l’avons vu précédemment, il est intéressant de ploter notre score face à nos différentes données, nous allons donc tous les tester rapidement et essayer d’observer.
Cette matrice de graphiques en dispersions nous donne un bonne aperçu de quel variables seront intéressantes à étudier.
# Préparation des données
df_model <- clean_data %>%
group_by(code_bureau_vote) %>%
slice_sample(n = 1) %>%
ungroup() %>%
select(where(is.numeric)) %>%
select(-contains("voix")) %>%
filter(!is.na(score_orientation)) %>%
slice_sample(n = 100)
write.csv(df_model, file = "big_score_training_data.csv", row.names = FALSE)
nzv <- nearZeroVar(df_model, saveMetrics = TRUE)
df_model <- df_model[, !nzv$nzv]
preProcValues <- preProcess(df_model, method = "medianImpute")
df_model <- predict(preProcValues, df_model)
num_cores <- parallel::detectCores() - 1
cl <- makeCluster(num_cores)
registerDoParallel(cl)
train_ctrl <- trainControl(
method = "repeatedcv",
number = 5,
repeats = 3,
verboseIter = TRUE,
allowParallel = FALSE
)
tune_grid <- expand.grid(
mtry = c(2, 4, 6, 8),
splitrule = c("variance", "extratrees"),
min.node.size = c(5, 10, 15)
)
df_model <- as.data.frame(df_model)
X <- df_model[, setdiff(names(df_model), "score_orientation")]
Y <- df_model$score_orientation
set.seed(123)
rf_model <- train(
x = X,
y = Y,
method = "ranger",
trControl = train_ctrl,
tuneGrid = tune_grid,
num.trees = 500,
importance = "impurity"
)
stopCluster(cl)
saveRDS(rf_model, file = "big_score_model.rds")
On commence par extraire les variables significatives de la random forest :
# Charger le modèle depuis le fichier RDS
rf_model <- readRDS("big_score_model.rds")
# Extraire l'importance des variables
importance_vars <- varImp(rf_model, scale = FALSE)
importance_df <- as.data.frame(importance_vars$importance)
importance_df$variable <- rownames(importance_df)
# Trier par importance décroissante
importance_df <- importance_df[order(-importance_df$Overall), ]
# Choisir un seuil d'importance (exemple : garder les variables dont l'importance est supérieure à 5% du max)
seuil <- 0.05 * max(importance_df$Overall)
selected_vars <- importance_df[importance_df$Overall >= seuil, ]
selected_vars
Puis on peut essayer d’analyser des profils types et les variables qui influent :
# Charger le dataset depuis le fichier CSV
model_data <- read.csv("big_score_training_data.csv")
# Sélection des colonnes utilisées dans le modèle
model_vars <- setdiff(colnames(model_data), "score_orientation")
# Fonction pour extraire plusieurs observations par tranche de `score_orientation`
extract_observations_group <- function(data, lower_bound, upper_bound, model_vars, n = 20) {
data %>%
filter(score_orientation >= lower_bound, score_orientation < upper_bound) %>%
select(all_of(c(model_vars, "score_orientation"))) %>%
slice_sample(n = n) # Prendre des observations aléatoires
}
# Création des 5 groupes d'observations
X_group1 <- extract_observations_group(model_data, 0.0, 0.2, model_vars, n = 20)
X_group2 <- extract_observations_group(model_data, 0.2, 0.4, model_vars, n = 20)
X_group3 <- extract_observations_group(model_data, 0.4, 0.6, model_vars, n = 20)
X_group4 <- extract_observations_group(model_data, 0.6, 0.8, model_vars, n = 20)
X_group5 <- extract_observations_group(model_data, 0.8, 1.0, model_vars, n = 20)
# Fonction pour calculer la moyenne des valeurs SHAP pour un groupe d'observations
compute_shapley_mean <- function(predictor, x_interest_group) {
shapley_results <- lapply(1:nrow(x_interest_group), function(i) {
x_interest <- x_interest_group[i, , drop = FALSE]
shapley <- Shapley$new(predictor, x.interest = x_interest)
shapley$results %>% mutate(observation_id = i)
})
shapley_combined <- do.call(rbind, shapley_results)
shapley_mean <- shapley_combined %>%
group_by(feature) %>%
summarise(mean_phi = mean(abs(phi)), .groups = 'drop')
return(shapley_mean)
}
# Calcul des valeurs SHAP moyennes pour chaque groupe
shapley_mean1 <- compute_shapley_mean(predictor, X_group1)
shapley_mean2 <- compute_shapley_mean(predictor, X_group2)
shapley_mean3 <- compute_shapley_mean(predictor, X_group3)
shapley_mean4 <- compute_shapley_mean(predictor, X_group4)
shapley_mean5 <- compute_shapley_mean(predictor, X_group5)
# Visualisation des profils types par tranche
plot_shapley_profile <- function(shapley_mean, title) {
ggplot(shapley_mean, aes(x = reorder(feature, -mean_phi), y = mean_phi)) +
geom_bar(stat = "identity", fill = "steelblue") +
coord_flip() +
labs(title = title, x = "Feature", y = "Valeur SHAP moyenne (abs)") +
theme_minimal()
}
# Plots des profils types pour chaque tranche
plot_shapley_profile(shapley_mean1, "Profil type pour la tranche [0.0 - 0.2[")
plot_shapley_profile(shapley_mean2, "Profil type pour la tranche [0.2 - 0.4[")
plot_shapley_profile(shapley_mean3, "Profil type pour la tranche [0.4 - 0.6[")
plot_shapley_profile(shapley_mean4, "Profil type pour la tranche [0.6 - 0.8[")
plot_shapley_profile(shapley_mean5, "Profil type pour la tranche [0.8 - 1.0]")
# Fonction pour calculer la moyenne des valeurs SHAP par groupe de variables
compute_shapley_influence <- function(shapley_means) {
shapley_means %>%
mutate(Group = case_when(
grepl("prop|population", feature) ~ "Démographie",
grepl("emplois|ouvriers|employes", feature) ~ "Emploi",
grepl("menages|logements", feature) ~ "Habitation",
TRUE ~ "Autre"
)) %>%
group_by(Group) %>%
summarise(
mean_phi = mean(mean_phi),
sd_phi = sd(mean_phi),
.groups = 'drop'
) %>%
arrange(desc(mean_phi))
}
# Calculer les moyennes SHAP pour chaque groupe d'observations
shapley_mean1_grouped <- compute_shapley_influence(shapley_mean1)
shapley_mean2_grouped <- compute_shapley_influence(shapley_mean2)
shapley_mean3_grouped <- compute_shapley_influence(shapley_mean3)
shapley_mean4_grouped <- compute_shapley_influence(shapley_mean4)
shapley_mean5_grouped <- compute_shapley_influence(shapley_mean5)
# Visualisation de la dispersion des valeurs SHAP par groupe
plot_group_distribution <- function(shapley_means, title) {
ggplot(shapley_means, aes(x = Group, y = mean_phi, fill = Group)) +
geom_boxplot(outlier.color = "red", outlier.shape = 1) +
geom_jitter(width = 0.2, alpha = 0.5) +
labs(
title = title,
x = "Groupes de variables",
y = "Valeur SHAP (importance absolue)"
) +
theme_minimal() +
theme(plot.title = element_text(hjust = 0.5))
}
# Plots pour chaque tranche de score
plot_group_distribution(shapley_mean1_grouped, "Distribution des valeurs SHAP [0.0 - 0.2[")
plot_group_distribution(shapley_mean2_grouped, "Distribution des valeurs SHAP [0.2 - 0.4[")
plot_group_distribution(shapley_mean3_grouped, "Distribution des valeurs SHAP [0.4 - 0.6[")
plot_group_distribution(shapley_mean4_grouped, "Distribution des valeurs SHAP [0.6 - 0.8[")
plot_group_distribution(shapley_mean5_grouped, "Distribution des valeurs SHAP [0.8 - 1.0]")
Nous voyons instantanément qu’il y a eu de gros changements dans l’intention de vote des Français entre 2012 et 2022. Sur ces cartes, l’intensité des couleurs représente la force des tendances politiques : plus la teinte est bleue, plus l’électorat vote à droite ; plus elle est rouge, plus l’électorat vote à gauche.
En 2012, très peu de communes montrent un vote majoritaire à droite. Le bleu est peu présent sur la carte, avec une concentration visible principalement dans certaines zones du Nord-Est de la France.
En 2017 et en 2022, le bleu est beaucoup plus représenté, notamment dans le Nord-Est où il domine largement et atteint souvent des teintes de bleu foncé. Cette évolution marque un basculement progressif d’une partie importante de l’électorat vers la droite, avec des contrastes régionaux de plus en plus marqués.
Cependant, certaines régions ont conservé une certaine stabilité dans leurs choix politiques. La Bretagne, par exemple, reste l’une des régions où le vote à gauche est resté dominant et où les évolutions dans les tendances politiques sont beaucoup moins marquées.
{width=32%}
<p style="font-style: italic;">Élection présidentielle 2012</p>
{width=32%}
<p style="font-style: italic;">Élection présidentielle 2017</p>
{width=32%}
<p style="font-style: italic;">Élection présidentielle 2022</p>